#pragma once
#include <iostream>
#include <chrono>
#include <thread>
#include "../common/net.hpp"
#include "../common/dispatcher.hpp"
#include"rpc_router.hpp"
#include"rpc_registry.hpp"
#include"rpc_topic.hpp"
#include"../client/rpc_client.hpp"

           
namespace RPC_project
{
    namespace server
    {
        //注册中心服务器 ,服务发现者和服务注册者的数据管理
        //功能：对服务注册和服务发现的request处理
        class RegistryServer
        {
            public:
                using ptr =std::shared_ptr<RegistryServer>;

                RegistryServer(int port )//监听端口是port ，监听地址可以通过0.0.0.0去监听当前主机上的全部IP地址
                    :_pd_manager(std::make_shared<ProviderAndDiscover>())
                    ,_dispatcher(std::make_shared<Dispather>())
                {
                    auto server_cb =std::bind(&ProviderAndDiscover::onServiceRequest, _pd_manager.get() ,
                        std::placeholders::_1,std::placeholders::_2);
                    _dispatcher->RegisterHandler<ServiceRequest>(MType::REQ_SERVICE ,server_cb);

                    
                    _server = RPC_project::ServerFactory::create(port);
                    auto message_cb =std::bind(&RPC_project::Dispather::onMessage ,_dispatcher.get() , 
                        std::placeholders::_1 ,std::placeholders::_2);
                    _server->SetMessageCallback(message_cb);

                    auto close_cb =std::bind(&RegistryServer::onConnectionShutdown ,this ,
                        std::placeholders::_1);
                    _server->SetCloseCallback(close_cb);
                    

                }
                void start()
                {
                    _server->start();
                }

            private:
                //可以扩展
                void onConnectionShutdown(const BaseConnection::ptr &conn)
                {
                    _pd_manager->onConnectionShutdown(conn);
                }
            private:
                ProviderAndDiscover::ptr _pd_manager;//服务发现者和服务注册者的管理对象
                BaseServer::ptr _server;
                Dispather::ptr _dispatcher;
        };

        //RPC服务器
        //功能：1. 对rpc的request进行处理  2.服务注册客户端模块（能向进行注册RPC服务）
        class RpcServer
        {
            public:
                using ptr =std::shared_ptr<RegistryServer>;
                //前面access_address是rpc服务提供端的地址信息 -- 当前rpc服务器对外的访问地址（云服务器 -- 监听地址与访问地址(外网地址)不同）
                //后面register_address是注册中心的地址信息 -- 启用服务注册连接注册中心进行服务注册用的
                RpcServer(const Address& access_address , bool enableRegistry = false , const Address& register_address = Address())
                    :_access_address(access_address)
                    ,_enableRegistry(enableRegistry)
                    ,_rpc_router(std::make_shared<RpcRouter>())
                    ,_dispatcher(std::make_shared<Dispather>())
                {
                    if(enableRegistry)
                    {
                        //实例化_reg_client
                        _reg_client= std::make_shared<client::RegistryClient>(register_address.first ,register_address.second);
                    }

                    //RPCserver 提供RPC服务
                    auto rpc_cb =std::bind(&RPC_project::server::RpcRouter::onRpcRequest , _rpc_router.get() ,
                    std::placeholders::_1 , std::placeholders::_2);
                    _dispatcher->RegisterHandler<RPC_project::RpcRequest>(MType::REQ_RPC, rpc_cb);

                    //监听所有IP地址的指定端口
                    _server = RPC_project::ServerFactory::create(access_address.second);
                    auto message_cb =std::bind(&RPC_project::Dispather::onMessage ,_dispatcher.get() , 
                        std::placeholders::_1 ,std::placeholders::_2);
                    _server->SetMessageCallback(message_cb);

                }

                void registerMethod(const ServiceDescribe::ptr &service)
                {
                    _rpc_router->registerMethod(service);
                    if(_enableRegistry)//启用了服务注册
                    {
                        _reg_client->registryMethod(service->methodName() ,_access_address);
                    }
                }

                void start()
                {
                    _server->start();
                }

            private:
                bool _enableRegistry;                   //是否启用注册的功能
                Address _access_address;                //访问地址(外网地址)
                client::RegistryClient::ptr _reg_client;//服务注册客户端
                RpcRouter::ptr _rpc_router;
                BaseServer::ptr _server;
                Dispather::ptr _dispatcher;
        };

        //发布订阅服务器        
        class SubscribePublishServer
        {
            public:
                using ptr =std::shared_ptr<SubscribePublishServer>;

                SubscribePublishServer(int port )//监听端口是port ，监听地址可以通过0.0.0.0去监听当前主机上的全部IP地址
                    :_topic_manager(std::make_shared<TopicManager>())
                    ,_dispatcher(std::make_shared<Dispather>())
                {
                    auto topic_cb =std::bind(&TopicManager::onTopicRequest, _topic_manager.get() ,
                        std::placeholders::_1,std::placeholders::_2);
                    _dispatcher->RegisterHandler<TopicRequest>(MType::REQ_TOPIC ,topic_cb);

                    _server = RPC_project::ServerFactory::create(port);
                    auto message_cb =std::bind(&RPC_project::Dispather::onMessage ,_dispatcher.get() , 
                        std::placeholders::_1 ,std::placeholders::_2);
                    _server->SetMessageCallback(message_cb);

                    auto close_cb =std::bind(&SubscribePublishServer::onConnectionShutdown ,this , std::placeholders::_1);
                    _server->SetCloseCallback(close_cb);
                    

                }
                void start()
                {
                    _server->start();
                }

            private:
                //可以扩展
                void onConnectionShutdown(const BaseConnection::ptr &conn)
                {
                    _topic_manager->onShutdown(conn);
                }
            private:
                TopicManager::ptr _topic_manager;//主题和订阅者的管理对象
                BaseServer::ptr _server;
                Dispather::ptr _dispatcher;
        };


    }
    
}